AnsibleのRole入門
Ansibleは選れた構成管理ツールですが、構成する内容が複雑になればなるほど辛くなります。 これはプログラム(ソースコード)と同じです。 複雑になった構成を整理し、可読性と再利用性を高めることが求められてきます。 今回はplaybookを整理する時に、最初に覚えなければならないRoleについてまとめます。
Roleとは?
Roleは、一言で言えばplaybookで読み込むモジュールです。 playbookは複数のRoleを読み込むことができるため、構成する内容を適切な粒度のRoleに分割し、それをインクルードする形でplaybookを構成するのです。 言い換えれば、Roleはクラス・モジュール・ソースファイルと言った概念と変わりません。 肥大化する構成を適切な粒度で分割するための道具です。
Roleの単位
Roleをどのような単位で作成するかは、ケースバイケースです。 詰め込みすぎたロールは、Managerクラスのような「良くわからないRole」になるでしょう。 また、細かく分割しすぎると見通しが悪くなるのも事実です。
一般的にミドルウェア単位などが適切だと思います。 アンチパターンとしてはサーバ単位にRoleを作成することです。 この場合、再利用性が乏しく、かつコピペが多くなりがちです。
Roleの構造
Roleはrolesディレクトリ配下に作成します。 例えば、apache2 Roleは、roles/apache2 ディレクトリの下に定義します。
各Roleの下には、tasks, defaults, vars, files, templates, mata, handlersと言ったディレクトリを作成して、Roleの定義を記述します。 この中で必須なのはtasksだけです。 tasks/main.yml が基本定義となるので、残りは随時覚えていきましょう。
site.yml roles/ apache2/ files/ templates/ tasks/ handlers/ vars/ defaults/ meta/
今回は各ディレクトリの簡単な説明だけを行います。
tasks
roleで実行されるtaskを定義します。 main.ymlが読み込まれ、残りのファイルはmain.ymlなどからincludeされでしょう。
defaults
main.ymlにroleで利用される変数のデフォルト値を定義します。 後述のvarsとの違いは、group_varsなどで変数を上書きできる点です。
vars
main.ymlにroleで利用される変数を定義します。 基本的に環境毎に変わる固定値などを記述し、group_varsなどで変数を上書きできません(厳密にはできるが、優先順位的にvarsはかなり強いため、扱い難い)。
files
copyモジュールでセットアップされるファイルを配置します。 テキストファイルでもバイナリファイルでも構いません。 シェルスクリプトのようなテキストファイルは後述のtemplatesに配置する方がベターでしょう。
templates
templateモジュールでセットアップされるJinja2形式のテキストファイルを配置します。 Jinja2形式のテキストファイルは、変数を埋め込むことができる点がfilesの下のファイルとの違いです。 変数がない場合であっても、後日変数化したい場合も多いので、最初からtemplatesに配置する方がベターでしょう。
mata
Roleのメタ情報を配置します。 実質的に、main.ymlにRoleの依存関係を記述することになります。 このRoleを実行するには依存するミドルウェアをインストールする別のRoleが必要、といったイメージです。
handlers
handlersには、主にサービスの再起動といった特定の条件で発火するイベントtaskを定義します。 別のRoleにて、Apacheの設定ファイルを変更した後、Apacheを再起動したいといったケースで利用します。 この場合、別のRoleからhandlerの「restart apache2 service」をnotifyすれば、期待する挙動となるのです。
簡単なRoleの作成
Apache2をインストールする簡単なRoleを作成してみます。
ディレクトリの作成
roles/apache2/tasks を作成します。
tasks/main.ymlの定義
RedHatとDebianに対応してみましょう。
--- - name: Install apache2 (RedHat). yum: name=httpd when: "ansible_os_family == 'RedHat'" - name: Install apache2 (Debian). apt: name=apache2 when: "ansible_os_family == 'Debian'"
Playbookの作成
site.ymlを作成します。
# # site.yml # - hosts: all sudo: yes remote_user: "{{ ansible_remote_user_name }}" roles: - apache2
まとめ
AnsibleのRoleを活用することで、肥大化するPlaybookを適切な単位に分割して整理することができます。 また、構造が決まっているため、どの情報がどこに書いてあるかを追いやすくなります。 ただし、構造や使い方を覚えなければなりません。